package org.tgcloud.group.service.manager;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.RateLimiter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.tgcloud.group.core.ExportUtils.ExcelUtils;
import org.tgcloud.group.core.ExportUtils.PicUtils;
import org.tgcloud.group.core.StringUtil;
import org.tgcloud.group.core.mapUtils.GeoUtils;
import org.tgcloud.group.core.mapUtils.TXMapUtils;
import org.tgcloud.group.core.mapUtils.data.LocationData;
import org.tgcloud.group.core.mapUtils.data.TXResultData;
import org.tgcloud.group.entity.Media;
import org.tgcloud.group.repository.MediaMapper;
import org.tgcloud.group.service.task.ExcelPicTask;
import org.tgcloud.group.service.task.MediaTask;
import org.tgcloud.group.web.controller.dto.media.MediaOtherMsgDTO;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.*;

/**
 * @Author: zhy
 * @Created: 2025-02-24-下午2:16
 * @Description:
 */
@Service
public class AsyncService {

    @Autowired
    private TXMapUtils txMapUtils;

    @Autowired
    private ExcelPicTask excelPicTask;

    @Autowired
    private MediaMapper mediaMapper;

    @Autowired
    private MediaTask mediaTask;

    @Autowired
    private PicUtils picUtils;

    @Autowired
    private GeoUtils geoUtils;

    @Async
    public void doGetLatAndLon() throws Exception{
        List<Media> mediaList = mediaMapper.selectAllNoLatList();
        int batchSize = 1000;
        int MAX_CONCURRENT_TASKS = 50; // 设置最大并发任务数
        RateLimiter rateLimiter = RateLimiter.create(5); // 每秒最多允许80个请求
        List<List<Media>> partitionedData = Lists.partition(mediaList, batchSize);
        ExecutorService executor = Executors.newFixedThreadPool(MAX_CONCURRENT_TASKS);
        CountDownLatch latch = new CountDownLatch(partitionedData.size());
        for (final List<Media> chunk : partitionedData) {
            executor.submit(() -> {
                try {
                    for (Media media : chunk){
                        MediaOtherMsgDTO dto = JSONObject.parseObject(media.getOtherMsg(), MediaOtherMsgDTO.class);
                        // 获取每个地方的经纬度
                        if (StringUtil.isNotBlank(dto.getSpecificLocation())){
                            String local = dto.getSpecificLocation();
                            if (!dto.getSpecificLocation().contains("省") && !dto.getSpecificLocation().contains("市")){
                                local = dto.getProvince() + dto.getCity() + dto.getArea() + dto.getSpecificLocation();
                            }
                            if (!dto.getSpecificLocation().contains("省") && dto.getSpecificLocation().contains("市")){
                                local = dto.getProvince() + dto.getArea() + dto.getSpecificLocation();
                            }
                            rateLimiter.acquire(); // 请求令牌，如果超出速率则等待
                            try {
                                LocationData location = txMapUtils.getGDGeocoderToLocation(local);
                                if (location != null){
                                    if (Objects.equals(location.getLat(), "0")){
                                        local = dto.getProvince() + dto.getCity() + dto.getBuildingName();
                                        location = txMapUtils.getGDGeocoderToLocation(local);
                                    }
                                    dto.setLongitude(location.getLng());
                                    dto.setLatitude(location.getLat());
                                    media.setLongitude(location.getLng());
                                    media.setLatitude(location.getLat());
                                }
                            }catch (Exception e){
                                System.out.println("错误======" + e.getMessage());
                                continue;
                            }
                            media.setOtherMsg(JSONObject.toJSONString(dto));
                            mediaMapper.updateLatAndLonById(media.getId(), media.getLatitude(), media.getLongitude(), media.getOtherMsg());
                            double longitude = Double.parseDouble(media.getLongitude());
                            double latitude = Double.parseDouble(media.getLatitude());
                            geoUtils.geoAdd(media.getId().toString(), longitude, latitude);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    // 释放许可，允许其他任务运行
                    latch.countDown();
                }
            });
        }
        latch.await(); // 等待所有任务完成
        executor.shutdown();
        mediaTask.doRefreshStatus = true;
    }



    @Async
    public void doGetExcelPic(MultipartFile file, String fileName) throws Exception{
        Integer picNum = ExcelUtils.readSignNum(file, MediaOtherMsgDTO.class, "pic");
        excelPicTask.doAddPic(fileName, file, picNum);
    }

    @Async
    public void doGetExcelPicByFilePath(String filePath, String fileName) throws Exception{
        picUtils.extractPictures(filePath, fileName);
    }


}
